"""
定时任务数据模型
定义定时任务的数据库模型
"""

import uuid
from datetime import datetime
from typing import Optional, Dict, Any
from sqlalchemy import Column, String, DateTime, Boolean, Integer, JSON, Text
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
from pydantic import BaseModel, Field

Base = declarative_base()

class ScheduledTask(Base):
    """定时任务模型"""
    
    __tablename__ = "scheduled_tasks"
    
    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    name = Column(String(100), nullable=False)
    description = Column(Text)
    question = Column(Text, nullable=False)  # 研究问题
    schedule_type = Column(String(20), nullable=False)  # cron, interval, date
    cron_expression = Column(String(50))  # 对于cron类型
    interval_seconds = Column(Integer)  # 对于interval类型
    start_date = Column(DateTime)  # 开始时间
    end_date = Column(DateTime)  # 结束时间
    enabled = Column(Boolean, default=True)
    session_id = Column(String(36))  # 关联会话ID
    task_metadata = Column(JSON)  # 额外元数据
    created_at = Column(DateTime, default=datetime.now)
    updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)

class TaskExecutionHistory(Base):
    """任务执行历史模型"""
    
    __tablename__ = "task_execution_history"
    
    id = Column(Integer, primary_key=True, autoincrement=True)
    task_id = Column(String(36), nullable=False)
    status = Column(String(20))  # success, failed, running
    result = Column(JSON)  # 执行结果
    started_at = Column(DateTime, default=datetime.now)
    completed_at = Column(DateTime)
    error_message = Column(Text)
    execution_time = Column(Integer)  # 执行时间(秒)

class DatabaseService:
    """数据库服务"""
    
    def __init__(self):
        self.engine = None
        self.SessionLocal = None
        
    def initialize(self, database_url: str):
        """初始化数据库连接"""
        try:
            self.engine = create_engine(database_url)
            self.SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=self.engine)
            
            # 创建表
            Base.metadata.create_all(self.engine)
            
            return True
        except Exception as e:
            print(f"数据库初始化失败: {e}")
            return False
    
    def create_task(self, task_data: Dict[str, Any]) -> Optional[ScheduledTask]:
        """创建定时任务"""
        try:
            if self.SessionLocal is None:
                raise RuntimeError("Database not initialized. Please call initialize() first.")
            session = self.SessionLocal()
            task = ScheduledTask(**task_data)
            session.add(task)
            session.commit()
            session.refresh(task)
            session.close()
            return task
        except Exception as e:
            print(f"创建定时任务失败: {e}")
            return None
    
    def get_task(self, task_id: str) -> Optional[ScheduledTask]:
        """获取定时任务"""
        try:
            if self.SessionLocal is None:
                raise RuntimeError("Database not initialized. Please call initialize() first.")
            session = self.SessionLocal()
            task = session.query(ScheduledTask).filter(ScheduledTask.id == task_id).first()
            session.close()
            return task
        except Exception as e:
            print(f"获取定时任务失败: {e}")
            return None
    
    def update_task(self, task_id: str, update_data: Dict[str, Any]) -> bool:
        """更新定时任务"""
        try:
            if self.SessionLocal is None:
                raise RuntimeError("Database not initialized. Please call initialize() first.")
            session = self.SessionLocal()
            task = session.query(ScheduledTask).filter(ScheduledTask.id == task_id).first()
            if task:
                for key, value in update_data.items():
                    setattr(task, key, value)
                session.commit()
                session.close()
                return True
            return False
        except Exception as e:
            print(f"更新定时任务失败: {e}")
            return False
    
    def delete_task(self, task_id: str) -> bool:
        """删除定时任务"""
        try:
            if self.SessionLocal is None:
                raise RuntimeError("Database not initialized. Please call initialize() first.")
            session = self.SessionLocal()
            task = session.query(ScheduledTask).filter(ScheduledTask.id == task_id).first()
            if task:
                session.delete(task)
                session.commit()
                session.close()
                return True
            return False
        except Exception as e:
            print(f"删除定时任务失败: {e}")
            return False
    
    def list_tasks(self, enabled_only: bool = False) -> list:
        """获取定时任务列表"""
        try:
            if self.SessionLocal is None:
                raise RuntimeError("Database not initialized. Please call initialize() first.")
            session = self.SessionLocal()
            query = session.query(ScheduledTask)
            if enabled_only:
                query = query.filter(ScheduledTask.enabled == True)
            tasks = query.all()
            session.close()
            return tasks
        except Exception as e:
            print(f"获取定时任务列表失败: {e}")
            return []
    
    def add_execution_history(self, history_data: Dict[str, Any]) -> bool:
        """添加执行历史记录"""
        try:
            if self.SessionLocal is None:
                raise RuntimeError("Database not initialized. Please call initialize() first.")
            session = self.SessionLocal()
            history = TaskExecutionHistory(**history_data)
            session.add(history)
            session.commit()
            session.close()
            return True
        except Exception as e:
            print(f"添加执行历史记录失败: {e}")
            return False
    
    def get_execution_history(self, task_id: str, limit: int = 10) -> list:
        """获取任务执行历史"""
        try:
            if self.SessionLocal is None:
                raise RuntimeError("Database not initialized. Please call initialize() first.")
            session = self.SessionLocal()
            history = session.query(TaskExecutionHistory)\
                .filter(TaskExecutionHistory.task_id == task_id)\
                .order_by(TaskExecutionHistory.started_at.desc())\
                .limit(limit)\
                .all()
            session.close()
            return history
        except Exception as e:
            print(f"获取执行历史记录失败: {e}")
            return []

# 全局数据库服务实例
db_service = DatabaseService()


class ScheduledTaskResponse(BaseModel):
    """定时任务响应模型"""
    id: str
    name: str
    description: Optional[str]
    question: str
    schedule_type: str
    cron_expression: Optional[str]
    interval_seconds: Optional[int]
    start_date: Optional[datetime]
    end_date: Optional[datetime]
    enabled: bool
    session_id: Optional[str]
    task_metadata: Optional[Dict[str, Any]]
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True
        arbitrary_types_allowed = True


class TaskExecutionHistoryResponse(BaseModel):
    """任务执行历史响应模型"""
    id: int
    task_id: str
    status: str
    result: Optional[Dict[str, Any]]
    started_at: datetime
    completed_at: Optional[datetime]
    error_message: Optional[str]
    execution_time: Optional[int]

    class Config:
        from_attributes = True
        arbitrary_types_allowed = True


class ScheduledTaskCreate(BaseModel):
    """创建定时任务请求模型"""
    name: str = Field(..., description="任务名称")
    description: Optional[str] = Field(None, description="任务描述")
    question: str = Field(..., description="研究问题")
    schedule_type: str = Field(..., description="调度类型 (cron, interval, date)")
    cron_expression: Optional[str] = Field(None, description="Cron表达式")
    interval_seconds: Optional[int] = Field(None, description="间隔秒数")
    start_date: Optional[datetime] = Field(None, description="开始时间")
    end_date: Optional[datetime] = Field(None, description="结束时间")
    enabled: bool = Field(default=True, description="是否启用")
    session_id: Optional[str] = Field(None, description="关联会话ID")
    task_metadata: Optional[Dict[str, Any]] = Field(None, description="任务元数据")


class ScheduledTaskUpdate(BaseModel):
    """更新定时任务请求模型"""
    name: Optional[str] = Field(None, description="任务名称")
    description: Optional[str] = Field(None, description="任务描述")
    question: Optional[str] = Field(None, description="研究问题")
    schedule_type: Optional[str] = Field(None, description="调度类型 (cron, interval, date)")
    cron_expression: Optional[str] = Field(None, description="Cron表达式")
    interval_seconds: Optional[int] = Field(None, description="间隔秒数")
    start_date: Optional[datetime] = Field(None, description="开始时间")
    end_date: Optional[datetime] = Field(None, description="结束时间")
    enabled: Optional[bool] = Field(None, description="是否启用")
    session_id: Optional[str] = Field(None, description="关联会话ID")
    task_metadata: Optional[Dict[str, Any]] = Field(None, description="任务元数据")


# 全局数据库服务实例
db_service = DatabaseService()
